package com.axend.sofa.ui.activity

import android.Manifest
import android.content.ContentUris
import android.content.Context
import android.content.Intent
import android.database.Cursor
import android.net.Uri
import android.os.Bundle
import android.os.Environment
import android.provider.DocumentsContract
import android.util.Log
import android.view.WindowManager
import androidx.activity.result.ActivityResultLauncher
import androidx.activity.result.contract.ActivityResultContracts
import androidx.lifecycle.lifecycleScope
import androidx.lifecycle.viewModelScope
import com.alibaba.android.arouter.facade.annotation.Autowired
import com.alibaba.android.arouter.facade.annotation.Route
import com.alibaba.android.arouter.launcher.ARouter
import com.axend.lib_base.R
import com.axend.lib_base.engine.toast.toast
import com.axend.lib_base.ext.click
import com.axend.lib_base.help.ble.BleMsgProcessor
import com.axend.lib_base.help.ble.enums.BleCommandTag
import com.axend.lib_base.utils.CommUtils
import com.axend.lib_base.utils.log.MyLogUtils
import com.axend.lib_base.view.dialog.CustomFirmwareUpdateDialog
import com.axend.lib_base.view.dialog.CustomFirmwareUpdateDialog.Companion.MODEL_SELECT_FILE
import com.axend.lib_service.ARouterPath
import com.axend.lib_service.Constant
import com.axend.sofa.BR
import com.axend.sofa.base.BaseBleVVDActivity
import com.axend.sofa.databinding.ActivityFirmwareUpdateBinding
import com.axend.sofa.viewmodel.FirmwareUpdateViewModel
import com.hjq.permissions.OnPermissionCallback
import com.hjq.permissions.Permission
import com.hjq.permissions.XXPermissions
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import java.io.File
import java.io.FileOutputStream

/**
 * @description firmware update activity
 * @author admins
 * @time 2025/3/11 9:11
 */
@Route(path = ARouterPath.ACTIVITY_FIRMWARE_UPDATE)
class FirmwareUpdateActivity :
    BaseBleVVDActivity<FirmwareUpdateViewModel, ActivityFirmwareUpdateBinding>() {

    @Autowired(name = Constant.ROUTER_KEY_FIRMWARE_VERSION)
    @JvmField
    var firmwareVersion: String = ""

    private val firmwareUpdateDialog by lazy { CustomFirmwareUpdateDialog(this) }

    private lateinit var filePickerLauncher: ActivityResultLauncher<Intent>
    override fun init(savedInstanceState: Bundle?) {
        super.init(savedInstanceState)
        // 添加FLAG_KEEP_SCREEN_ON标志使屏幕常亮
        window.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON)
        ARouter.getInstance().inject(this)
        mBinding.setVariable(BR.viewmodel, mViewModel)
        mBinding.executePendingBindings()
        initClick()
        initObserver()

        filePickerLauncher = registerForActivityResult(
            ActivityResultContracts.StartActivityForResult()
        ) { result ->
            if (result.resultCode == RESULT_OK) {
                val data: Intent? = result.data
                data?.data?.also { uri ->
                    val filePath = getAbsolutePathFromUri(this, uri)
                    mViewModel.setFirmwarePath(filePath!!)

                }
            }
        }
    }

    private fun initObserver() {
        mViewModel.firmwarePath.observe(this) { filePath ->
            firmwareUpdateDialog.setModel(MODEL_SELECT_FILE).show()
            firmwareUpdateDialog.setFirmwarePath(filePath)
        }
        mViewModel.firmwareCurrentFrame.observe(this) { progress ->
            mViewModel.firmwareTotalFrame.value?.let { total ->
                if (firmwareUpdateDialog.isShowing) {
                    firmwareUpdateDialog.setProgress(progress, total)
                }
            }
        }
        mViewModel.firmwareUpdateSuccess.observe(this) { isSuccess ->
            if (isSuccess) {
                firmwareUpdateDialog.setModel(CustomFirmwareUpdateDialog.MODEL_SUCCESS)
            } else {
                firmwareUpdateDialog.setModel(CustomFirmwareUpdateDialog.MODEL_FAILED)
            }

        }
    }

    private fun initClick() {
        mViewModel.setFirmwareVersion(firmwareVersion)
        mBinding.llFileDialog.click {
            XXPermissions.with(this).permission(arrayOf(Permission.MANAGE_EXTERNAL_STORAGE))
                .request(object : OnPermissionCallback {
                    override fun onGranted(permissions: MutableList<String>, allGranted: Boolean) {
                        if (allGranted){
                            showFileChooser()
                        }
                    }

                    override fun onDenied(
                        permissions: MutableList<String>,
                        doNotAskAgain: Boolean
                    ) {
                        super.onDenied(permissions, doNotAskAgain)
                        if (doNotAskAgain) {
                            toast(getString(com.axend.lib_base.R.string.app_tips_permission_grant))
                            XXPermissions.startPermissionActivity(
                                this@FirmwareUpdateActivity,
                                permissions
                            )
                        } else {
                            toast(getString(com.axend.lib_base.R.string.app_tips_permission_fail))
                        }
                    }

                })
        }
        firmwareUpdateDialog.setUpgradeClickListener {
            if (mViewModel.firmwarePath.value.isNullOrEmpty()) {
                toast(CommUtils.getString(R.string.app_tips_select_file_end_bin))
                return@setUpgradeClickListener
            }
            var file = File(mViewModel.firmwarePath.value)
            if (!file.name.endsWith(".bin")) {
                toast(CommUtils.getString(R.string.app_tips_select_file_end_bin))
                return@setUpgradeClickListener
            }
            mViewModel.writeFirmwareUpdateMsg()
            firmwareUpdateDialog.setModel(CustomFirmwareUpdateDialog.MODEL_LOADING)
        }

        firmwareUpdateDialog.setDismissClickListener {
            /*获取版本*/
            mViewModel.writeBleMsg(
                BleMsgProcessor.encodeMsg(
                    BleCommandTag.GET_VERSION.getMarkFixCommand(),
                    BleCommandTag.GET_VERSION
                ))
            firmwareUpdateDialog.dismiss()
        }

    }


    private fun showFileChooser() {
        val intent = Intent(Intent.ACTION_GET_CONTENT)
        intent.type = "application/octet-stream" // 设置为所有文件类型
        intent.addCategory(Intent.CATEGORY_OPENABLE)

        // 设置文件类型过滤器，这里我们只允许.bin文件
        intent.putExtra(Intent.EXTRA_MIME_TYPES, arrayOf("application/octet-stream"))
        // 启动文件选择器
        filePickerLauncher.launch(intent)
    }


    private fun getAbsolutePathFromUri(context: Context, uri: Uri): String? {
        if (DocumentsContract.isDocumentUri(context, uri)) {
            val docId = DocumentsContract.getDocumentId(uri)
            // 外部存储文档
            if ("com.android.externalstorage.documents" == uri.authority) {
                val idParts = docId.split(":").toTypedArray()
                if (idParts.size == 2 && idParts[0] == "primary") {
                    return "${Environment.getExternalStorageDirectory()}/${idParts[1]}"
                } else if (idParts.size == 2 && idParts[0] != "primary") {
                    // 假设 U 盘挂载路径为 /storage/usb0
                    return "/storage/${idParts[0]}/${idParts[1]}"
                }
            } else if (uri.authority == "com.android.providers.downloads.documents") {
                val idStr = if (docId.startsWith("msf:")) {
                    // 处理 "msf:" 前缀，提取数字部分
                    docId.split(":")[1]
                } else {
                    // 没有前缀，直接使用 docId
                    docId
                }
                val id = idStr.toLongOrNull()
                return if (id != null) {
                    val contentUri = ContentUris.withAppendedId(
                        Uri.parse("content://downloads/public_downloads"),
                        id
                    )
                    try {
                        getDataColumn(context, contentUri, null, null)
                            ?: getFilePathFromUri(context, uri) // 回退方案
                    } catch (e: IllegalArgumentException) {
                        getFilePathFromUri(context, uri) // 如果 URI 无效，使用原始 URI
                    }
                } else {
                    // 处理错误：docId 无效
                    null
                }
            }
        } else if ("content" == uri.scheme) {
            return getDataColumn(context, uri, null, null)
        } else if ("file" == uri.scheme) {
            return uri.path
        }
        return null
    }


    private fun getDataColumn(
        context: Context,
        uri: Uri?,
        selection: String?,
        selectionArgs: Array<String>?
    ): String? {
        var cursor: Cursor? = null
        val column = "_data"
        val projection = arrayOf(column)
        try {
            cursor =
                context.contentResolver.query(uri!!, projection, selection, selectionArgs, null)
            if (cursor != null && cursor.moveToFirst()) {
                val columnIndex = cursor.getColumnIndexOrThrow(column)
                return cursor.getString(columnIndex)
            }
        } finally {
            cursor?.close()
        }
        return null
    }

   private fun getFilePathFromUri(context: Context, uri: Uri): String? {
        return try {
            context.contentResolver.openInputStream(uri)?.use { inputStream ->
                val file = File(context.cacheDir, "sensor_file")
                FileOutputStream(file).use { outputStream ->
                    inputStream.copyTo(outputStream)
                }
                file.absolutePath
            }
        } catch (e: Exception) {
            e.printStackTrace()
            null
        }
    }

}